<script setup lang="ts">
import {
  NButton,
  NSpace,
  NDataTable,
  NInput,
  type DataTableColumns,
  NPagination,
  NForm,
  NFormItem,
  NSelect,
  useDialog,
  useMessage,
  NModal,
  NDatePicker,
  type FormRules,
  type FormInst,
  type SelectOption,
  NTreeSelect
} from 'naive-ui'
import { h, computed, onDeactivated, onMounted, onUnmounted, reactive, ref, shallowRef } from 'vue'
import TableView from '@/components/TableView.vue'
import EllipseAction from '@/views/common/EllipseAction'
import type { BatchTableRowModelV2 } from '@/api/batchV2'
import useFlush from '@/hooks/useFlush'
import { useRouter } from 'vue-router'
import { sendRequest } from '@/utils/api'
import VDialogContent from '@/views/OA/Common/DialogContent.vue'
import type { HttpResponse, HttpResponsePagination } from '@/utils/http'
import type { CommonSelectOptionModel } from '@/api/batch'
import type { DicTreeModel } from '@/api/dic'
import axios from 'axios'

interface BatchTableQueryForm {
  batchName: string | null
  pointStatusCode: string | null
  solicitMethodCode: string | null
  creator: string | null
  receiver: string | null
  transferor: string | null
  receiveStartTime: string | null
  receiveEndTime: string | null
  collectorId: string | null
}

useFlush('flushBatch', () => queryTableData())
const router = useRouter()
const dialog = useDialog()
const message = useMessage()

const djStatusOptions = shallowRef<CommonSelectOptionModel[]>([])
const djStatusLoading = ref(false)
const queryDjStatusOptions = async () => {
  try {
    djStatusLoading.value = true
    const [error, res] = await sendRequest<HttpResponse<CommonSelectOptionModel[]>>({
      module: 'batch',
      api: 'djStatusList'
    })
    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)

    djStatusOptions.value = res.data
  } catch (error) {
    console.log(error)
  } finally {
    djStatusLoading.value = false
  }
}

const clueMethodOptions = reactive<DicTreeModel[]>([])
const clueMethodLoading = ref(false)
const queryClueMethodOptions = async () => {
  clueMethodLoading.value = true
  try {
    const [error, res] = await sendRequest<HttpResponse<DicTreeModel[]>>({
      module: 'dic',
      api: 'getTree',
      override: {
        params: {
          dicCode: 'A30'
        }
      }
    })

    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    clueMethodOptions.length = 0
    clueMethodOptions.push(...(res.data[0] ? res.data[0].children || [] : []))
  } catch (error) {
    console.error(error)
  } finally {
    clueMethodLoading.value = false
  }
}
const isTrue = ref(false)
const changeTree = (v: string) => {
  formData.solicitMethodCode = v
  if (formData.solicitMethodCode === 'A3007') {
    isTrue.value = true
  } else {
    isTrue.value = false
  }
}

const tableData = ref<BatchTableRowModelV2[]>([])
const tableLoading = ref(false)
const queryTableData = async (flush = false) => {
  if (flush) paginationReactive.page = 1
  try {
    tableLoading.value = true
    const [error, res] = await sendRequest<HttpResponsePagination<BatchTableRowModelV2>>({
      module: 'batchV2',
      api: 'list',
      override: {
        params: {
          limit: paginationReactive.pageSize,
          page: paginationReactive.page,
          ...formData
        }
      }
    })
    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)

    tableData.value = res.data.list
    paginationReactive.itemCount = res.data.totalCount
  } catch (error) {
    console.log(error)
  } finally {
    tableLoading.value = false
  }
}

const formData = reactive<BatchTableQueryForm>({
  batchName: null,
  pointStatusCode: null,
  solicitMethodCode: null,
  creator: null,
  receiver: null,
  transferor: null,
  receiveStartTime: null,
  receiveEndTime: null,
  collectorId: null
})

const resetFormData = () => {
  formData.batchName = null
  formData.pointStatusCode = null
  formData.solicitMethodCode = null
  formData.creator = null
  formData.receiver = null
  formData.transferor = null
  formData.receiveStartTime = null
  formData.receiveEndTime = null
  formData.collectorId = null
  // queryTableData(true)
}

const startEndTime = computed<[string, string] | null>({
  get: () => {
    if (!formData.receiveStartTime || !formData.receiveEndTime) return null
    return [formData.receiveStartTime, formData.receiveEndTime] as [string, string]
  },
  set: (val: [string, string] | null) => {
    formData.receiveStartTime = val ? val[0] : null
    formData.receiveEndTime = val ? val[1] : null
  }
})

const paginationReactive = reactive({
  page: 1,
  pageSize: 10,
  showSizePicker: true,
  pageSizes: [10, 20, 50, 100, 500],
  itemCount: 0,
  onChange: (page: number) => {
    paginationReactive.page = page
    queryTableData()
  },
  onUpdatePageSize: (pageSize: number) => {
    paginationReactive.pageSize = pageSize
    paginationReactive.page = 1
    queryTableData()
  }
})

let cancelToken = axios.CancelToken.source()
const columns: DataTableColumns<BatchTableRowModelV2> = [
  {
    title: '批次编号',
    key: 'batchCode',
    width: '130rem',
    align: 'center'
  },
  {
    title: '批次名称',
    key: 'batchName',
    align: 'center'
  },
  {
    title: '点交状态',
    key: 'pointStatus',
    width: '90rem',
    align: 'center'
  },
  {
    title: '征集方式',
    key: 'solicitMethod',
    width: '90rem',
    align: 'center'
  },
  {
    title: '移交人',
    key: 'transferor',
    width: '90rem',
    align: 'center'
  },
  {
    title: '接收人',
    key: 'receiver',
    width: '120rem',
    align: 'center',
    ellipsis: {
      tooltip: {
        maxWidth: 350
      }
    }
  },
  {
    title: '接收时间',
    key: 'receiveTime',
    align: 'center',
    ellipsis: {
      tooltip: true
    }
  },
  {
    title: '征集数量',
    key: 'solicitNum',
    width: '90rem',
    align: 'center'
  },
  {
    title: '证书发放',
    key: 'certificateType',
    render: (e) => e.certificateType || '/',
    align: 'center',
    width: '100px'
  },
  {
    title: '创建人',
    key: 'creator',
    width: '90rem',
    align: 'center'
  },
  {
    title: () => h('div', { style: 'text-align: center' }, '操作'),
    key: 'action',
    align: 'center',
    width: '200px',
    render: (e) => {
      return h(EllipseAction, {
        actions: () =>
          [
            h(
              NButton,
              {
                color: '#6CB187',
                quaternary: true,
                size: 'small',
                style: {
                  display: e.detail ? 'inline-flex' : 'none'
                },
                onClick: () => {
                  router.push({
                    name: 'batchDetail',
                    params: {
                      id: e.id
                    },
                    query: {
                      isCreated: String(e.createTime === e.updateTime),
                      isEdited: String(e.createTime !== e.updateTime),
                      isIdentified: 'false',
                      isRegistered: 'false',
                      isNoIdentify: 'false',
                      redirect: router.currentRoute.value.fullPath
                    }
                  })
                }
              },
              { default: () => '详情' }
            ),
            h(
              NButton,
              {
                color: '#6CB187',
                quaternary: true,
                size: 'small',
                style: {
                  display: 'inline-flex'
                },
                onClick: async () => {
                  cancelToken.cancel()
                  cancelToken = axios.CancelToken.source()
                  try {
                    const [error, res] = await sendRequest({
                      module: 'batch',
                      api: 'identifyList',
                      override: {
                        params: {
                          batchId: e.id
                        },
                        cancelToken: cancelToken.token
                      }
                    })
                    if (error) throw error
                    if (res.code !== 0) throw new Error(res.msg)
                    if (!res.data || res.data.length === 0) {
                      return message.warning('暂未鉴定申请')
                    }
                  } catch (error) {
                    if (error instanceof Error) message.error(error.message)
                    console.error(error)
                    return
                  }

                  router.push({
                    name: 'batchDetail',
                    params: {
                      id: e.id
                    },
                    query: {
                      isCreated: 'false',
                      isEdited: 'false',
                      isIdentified: String(e.identifyStatusCode === 'A4104' && e.identifyRegister),
                      isRegistered: String(
                        e.click ||
                          (e.identifyStatusCode === 'A4104' && !e.identifyRegister) ||
                          e.pointStatusCode === 'A4202'
                      ),
                      isNoIdentify: String(e.identifyStatusCode === 'A4102'),
                      redirect: router.currentRoute.value.fullPath
                    }
                  })
                }
              },
              { default: () => '鉴定详情' }
            ),
            h(
              NButton,
              {
                color: '#6CB187',
                quaternary: true,
                size: 'small',
                style: {
                  display: e.edit ? 'inline-flex' : 'none'
                },
                onClick() {
                  router.push({
                    name: 'editBatch',
                    params: {
                      id: e.id
                    },
                    query: {
                      redirect: router.currentRoute.value.fullPath
                    }
                  })
                }
              },
              { default: () => '编辑' }
            ),
            h(
              NButton,
              {
                color: '#FC355D',
                quaternary: true,
                size: 'small',
                style: {
                  display: e.delete ? 'inline-flex' : 'none'
                },
                onClick: () => handleDeleteBatch(e.id)
              },
              { default: () => '删除' }
            ),
            h(
              NButton,
              {
                color: '#6CB187',
                quaternary: true,
                size: 'small',
                style: {
                  display: e.identifyApply ? 'inline-flex' : 'none'
                },
                onClick() {
                  router.push({
                    name: 'identifyApply',
                    params: {
                      id: e.id
                    },
                    query: {
                      redirect: router.currentRoute.value.fullPath
                    }
                  })
                }
              },
              { default: () => '鉴定申请' }
            ),
            h(
              NButton,
              {
                color: '#6CB187',
                quaternary: true,
                size: 'small',
                style: {
                  display: e.identifyRegister ? 'inline-flex' : 'none'
                },
                onClick: () => {
                  router.push({
                    name: 'registerTF',
                    params: {
                      id: e.id
                    },
                    query: {
                      redirect: router.currentRoute.value.fullPath
                    }
                  })
                }
              },
              { default: () => '鉴定登记' }
            ),
            h(
              NButton,
              {
                color: '#6CB187',
                quaternary: true,
                size: 'small',
                style: {
                  display: e.noNeed ? 'inline-flex' : 'none'
                },
                onClick: () => handleNotIdentity(e.id)
              },
              { default: () => '无需鉴定' }
            ),
            h(
              NButton,
              {
                color: '#6CB187',
                quaternary: true,
                size: 'small',
                style: {
                  display: e.finished ? 'inline-flex' : 'none'
                },
                onClick: () => handleEndIdentity(e.id)
              },
              { default: () => '结束鉴定' }
            ),
            h(
              NButton,
              {
                color: '#6CB187',
                quaternary: true,
                size: 'small',
                style: {
                  display: e.click ? 'inline-flex' : 'none'
                },
                onClick: () => {
                  router.push({
                    name: 'dJ',
                    params: {
                      id: e.id
                    },
                    query: {
                      redirect: router.currentRoute.value.fullPath
                    }
                  })
                }
              },
              { default: () => '点交' }
            ),
            h(
              NButton,
              {
                color: '#6CB187',
                quaternary: true,
                size: 'small',
                style: {
                  display: e.clickConfirm ? 'inline-flex' : 'none'
                },
                onClick: () => {
                  router.push({
                    name: 'dJConfirm',
                    params: {
                      id: e.id
                    },
                    query: {
                      redirect: router.currentRoute.value.fullPath
                    }
                  })
                }
              },
              { default: () => '点交确认' }
            ),
            h(
              NButton,
              {
                color: '#6CB187',
                quaternary: true,
                size: 'small',
                style: {
                  display: e.temporary ? 'inline-flex' : 'none'
                },
                onClick: () => {
                  // @ts-ignore
                  formValue.batchId = e.id
                  dJSaveModalVisible.value = true
                }
              },
              { default: () => '暂存' }
            )
            // h(
            //   NButton,
            //   {
            //     color: '#6CB187',
            //     quaternary: true,
            //     size: 'small',
            //     style: {
            //       display: e.supplement ? 'inline-flex' : 'none'
            //     },
            //     onClick: () => {
            //       router.push({
            //         name: 'addAttachments',
            //         params: {
            //           id: e.id
            //         },
            //         query: {
            //           redirect: router.currentRoute.value.fullPath
            //         }
            //       })
            //     }
            //   },
            //   { default: () => '补充附件' }
            // )
          ].filter((item) => (!item.props?.style ? true : item.props?.style.display !== 'none'))
      })
    }
  }
]

const dJSaveModalVisible = ref(false)
const djSaveFormInst = ref<FormInst | null>(null)
const formValue = reactive({
  batchId: null,
  remark: null,
  storagePlace: null
})
const rules: FormRules = {
  storagePlace: {
    required: true,
    message: '请输入存放位置',
    trigger: ['blur', 'input']
  }
}
const handleDJSave = () => {
  djSaveFormInst.value?.validate(async (err) => {
    if (err) return
    try {
      const [error, res] = await sendRequest({
        module: 'batch',
        api: 'temporaryStorage',
        override: {
          data: formValue
        }
      })
      if (error) throw error
      if (res.code !== 0) throw new Error(res.msg)

      message.success('暂存成功！')
      formValue.remark = null
      formValue.storagePlace = null
      queryTableData()
    } catch (error) {
      if (error instanceof Error) {
        message.error(error.message)
      }
    } finally {
      dJSaveModalVisible.value = false
    }
  })
}

const modalVisible = ref(false)
const modalTitle = ref('')
const modalContent = ref('')
const modalConfirm = ref<(() => Promise<void>) | null>()
const handleModalClose = () => {
  modalVisible.value = false
  modalTitle.value = ''
  modalContent.value = ''
  modalConfirm.value = null
}

const handleNotIdentity = (id: number) => {
  modalVisible.value = true
  modalTitle.value = '提示'
  modalContent.value = '当前批次是否无需鉴定？'
  modalConfirm.value = async () => {
    try {
      const [error, res] = await sendRequest({
        module: 'batchV2',
        api: 'withoutIdentify',
        override: {
          params: {
            batchId: id
          }
        }
      })
      if (error) throw error
      if (res.code !== 0) throw new Error(res.msg)
      message.success(res.msg)
      queryTableData()
      modalVisible.value = false
    } catch (error: any) {
      message.error(error.message)
    }
  }
}

const handleEndIdentity = (id: number) => {
  modalVisible.value = true
  modalTitle.value = '提示'
  modalContent.value = '是否对当前物品结束鉴定？'
  modalConfirm.value = async () => {
    try {
      const [error, res] = await sendRequest({
        module: 'batch',
        api: 'finishIdentify',
        override: {
          params: {
            batchId: id
          }
        }
      })
      if (error) throw error
      if (res.code !== 0) throw new Error(res.msg)
      message.success(res.msg)
      queryTableData()
      modalVisible.value = false
    } catch (error: any) {
      message.error(error.message)
    }
  }
}

const handleDeleteBatch = (id: number) => {
  modalVisible.value = true
  modalTitle.value = '提示'
  modalContent.value = '是否删除当前批次？'
  modalConfirm.value = async () => {
    try {
      const [error, res] = await sendRequest({
        module: 'batchV2',
        api: 'delete',
        override: {
          data: [id]
        }
      })
      if (error) throw error
      if (res.code !== 0) throw new Error(res.msg)
      message.success(res.msg)
      queryTableData()
      modalVisible.value = false
    } catch (error: any) {
      message.error(error.message)
    }
  }
}

const exportLoading = ref(false)
const handleExport = async () => {
  exportLoading.value = true
  try {
    const [error, res, headers] = await sendRequest<Blob>({
      module: 'batchV2',
      api: 'exportBatch',
      override: {
        params: {
          limit: paginationReactive.pageSize,
          page: paginationReactive.page,
          ...formData
        }
      }
    })
    if (error) throw error

    // download Blob
    console.log(headers)
    const filename = headers['content-disposition']?.split('filename=')[1] || '批次列表.xls'
    const blob = new Blob([res], {
      type: headers['content-type']
    })
    const url = window.URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = window.decodeURIComponent(filename)
    a.click()
    window.URL.revokeObjectURL(url)
  } catch (error) {
    if (error instanceof Error) message.error(error.message)
    console.error(error)
  } finally {
    exportLoading.value = false
  }
}

const ccc = ref<any[]>([])
async function fetchCollectors() {
  const [error, res] = await sendRequest({
    module: 'clue',
    api: 'listCollectorOptions'
  })
  if (error) throw error
  if (res.code !== 0) throw new Error(res.msg)
  ccc.value = res.data
}

onMounted(() => {
  queryDjStatusOptions()
  queryClueMethodOptions()
  queryTableData()
  fetchCollectors()
})

onUnmounted(() => {
  dialog.destroyAll()
  modalConfirm.value = null
  modalContent.value = ''
  modalTitle.value = ''
  modalVisible.value = false
})
onDeactivated(() => {
  dialog.destroyAll()
  modalConfirm.value = null
  modalContent.value = ''
  modalTitle.value = ''
  modalVisible.value = false
})
</script>

<template>
  <TableView class="batch">
    <template #form>
      <NForm
        label-placement="left"
        label-width="85rem"
        :show-feedback="false"
        class="batch-form"
        @keydown.enter="queryTableData(true)"
      >
        <NFormItem label="批次名称：">
          <NInput
            v-model:value="formData.batchName"
            placeholder="请输入批次名称"
            clearable
          />
        </NFormItem>
        <NFormItem label="点交状态：">
          <NSelect
            v-model:value="formData.pointStatusCode"
            :options="(djStatusOptions as unknown as SelectOption[])"
            :loading="djStatusLoading"
            label-field="name"
            placeholder="请选择点交状态"
            style="width: 180rem"
            clearable
          />
        </NFormItem>
        <NFormItem label="征集方式：">
          <NTreeSelect
            v-model:value="formData.solicitMethodCode"
            :options="clueMethodOptions"
            :loading="clueMethodLoading"
            placeholder="请选择征集方式"
            clearable
            style="width: 450px;margin-right: 20px;'"
            key-field="code"
            label-field="name"
            @update-value="changeTree"
          />
        </NFormItem>
        <NFormItem label="藏家：">
          <NSelect
            v-model:value="formData.collectorId"
            placeholder="请选择藏家"
            filterable
            :options="ccc"
            clearable
          />
        </NFormItem>
        <NFormItem label="移交人：">
          <NInput
            v-model:value="formData.transferor"
            placeholder="请输入移交人"
            clearable
          />
        </NFormItem>
        <NFormItem label="接收人：">
          <NInput
            v-model:value="formData.receiver"
            placeholder="请输入接收人"
            clearable
          />
        </NFormItem>
        <NFormItem label="创建人：">
          <NInput
            v-model:value="formData.creator"
            placeholder="请输入创建人"
            clearable
          />
        </NFormItem>
        <NFormItem
          label="接收时间："
          class="date-picker"
        >
          <NDatePicker
            v-model:formatted-value="startEndTime"
            format="yyyy-MM-dd HH:mm:ss"
            type="datetimerange"
            placeholder="请选择接收时间"
            clearable
          />
        </NFormItem>
      </NForm>

      <NSpace
        style="grid-column: span 5"
        justify="space-between"
      >
        <NSpace>
          <NButton
            :disabled="tableLoading"
            :loading="tableLoading"
            color="#6CB187"
            ghost
            style="min-width: 78rem"
            @click="queryTableData(true)"
          >
            查询
          </NButton>
          <NButton
            :disabled="tableLoading"
            color="#6CB187"
            style="min-width: 78rem"
            ghost
            @click="resetFormData"
          >
            重置
          </NButton>
        </NSpace>

        <NSpace>
          <NButton
            type="primary"
            class="batch-add-btn"
            ghost
            :disabled="exportLoading"
            :loading="exportLoading"
            @click="handleExport"
          >
            导出
          </NButton>
          <NButton
            color="#6CB187"
            class="batch-add-btn"
            @click="
              $router.push({
                name: 'addBatch',
                query: {
                  redirect: $route.fullPath
                }
              })
            "
          >
            新增
          </NButton>
        </NSpace>
      </NSpace>
    </template>
    <template #table="props">
      <n-data-table
        v-bind="props"
        :data="tableData"
        :columns="columns"
        :loading="tableLoading"
        bordered
      />
    </template>
    <template #pagination>
      <NPagination
        show-size-picker
        show-quick-jumper
        :page-sizes="paginationReactive.pageSizes"
        :item-count="paginationReactive.itemCount"
        :page="paginationReactive.page"
        :page-size="paginationReactive.pageSize"
        @update:page="paginationReactive.onChange"
        @update:page-size="paginationReactive.onUpdatePageSize"
      >
        <template #suffix>页</template>
        <template #prefix>
          <span style="font-size: 14px">共{{ paginationReactive.itemCount }}条</span>
        </template>
      </NPagination>
    </template>
  </TableView>

  <NModal
    :auto-focus="false"
    v-model:show="modalVisible"
  >
    <VDialogContent
      @close="handleModalClose"
      @submit="modalConfirm && modalConfirm()"
      :title="modalTitle"
    >
      <div style="width: 300rem; height: 100rem; text-align: center; line-height: 100rem">
        {{ modalContent }}
      </div>
    </VDialogContent>
  </NModal>

  <NModal
    :auto-focus="false"
    v-model:show="dJSaveModalVisible"
  >
    <VDialogContent
      @close="dJSaveModalVisible = false"
      @submit="handleDJSave"
      title="存放地"
    >
      <NSpace>
        <NForm
          ref="djSaveFormInst"
          :model="formValue"
          :rules="rules"
          label-placement="left"
          :label-width="85"
          label-align="right"
        >
          <NSpace>
            <NFormItem
              label="存放位置:"
              path="storagePlace"
            >
              <NInput
                v-model:value="formValue.storagePlace"
                placeholder="请输入存放位置"
                clearable
                style="width: 250px"
              />
            </NFormItem>
          </NSpace>
          <NSpace>
            <NFormItem
              label="备注:"
              path="remark"
            >
              <NInput
                v-model:value="formValue.remark"
                placeholder="请输入备注"
                clearable
                type="textarea"
                style="width: 250px"
              />
            </NFormItem>
          </NSpace>
        </NForm>
      </NSpace>
    </VDialogContent>
  </NModal>
</template>

<style scoped lang="scss">
.batch {
  padding: 29rem 30rem;
  gap: 25rem 0;
}

.batch-form {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 15rem 20rem;

  .date-picker {
    grid-column: span 2;
  }

  .n-date-picker,
  .n-select {
    flex: 1;
  }

  .batch-add-btn {
    width: 78rem;
    // margin-left: auto;
  }
}
</style>
